"""
路由管理API端点
提供路由的增删改查和权限关联功能
"""

from fastapi import APIRouter, Depends, HTTPException, status, Query
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select, and_, or_, func
from sqlalchemy.orm import selectinload
from typing import List, Optional
import logging

from app.core.database import get_db
from app.models.auth import Route, Permission, RoutePermission, User
from app.schemas.route import (
    RouteResponse, RouteListResponse, RouteCreate, RouteUpdate,
    RoutePermissionResponse, RoutePermissionAssign
)
from app.schemas.common import BaseResponse
from app.services.route_service import RouteService
from app.core.dependencies import (
    get_current_active_user, require_route_view, require_route_manage
)

logger = logging.getLogger(__name__)

router = APIRouter()
route_service = RouteService()


@router.get("", response_model=BaseResponse[RouteListResponse])
async def get_routes(
    parent_id: Optional[int] = Query(None, description="父路由ID"),
    is_menu: Optional[bool] = Query(None, description="是否菜单项"),
    is_active: Optional[bool] = Query(True, description="是否启用"),
    search: Optional[str] = Query(None, description="搜索关键词"),
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(require_route_view)
):
    """
    获取路由列表
    
    - **parent_id**: 父路由ID，为空则获取顶级路由
    - **is_menu**: 是否菜单项
    - **is_active**: 是否启用
    - **search**: 搜索关键词（路由名称、显示名称、描述）
    """
    try:
        result = await route_service.get_routes(
            db, parent_id=parent_id, is_menu=is_menu, 
            is_active=is_active, search=search
        )
        
        return BaseResponse(
            data=result,
            message="获取路由列表成功",
            success=True
        )
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"获取路由列表失败：{str(e)}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="获取路由列表失败"
        )


@router.get("/menu", response_model=BaseResponse[List[RouteResponse]])
async def get_menu_routes(
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(get_current_active_user)
):
    """
    获取当前用户可访问的菜单路由
    根据用户权限过滤路由
    """
    try:
        result = await route_service.get_user_menu_routes(db, current_user)
        
        return BaseResponse(
            data=result,
            message="获取菜单路由成功",
            success=True
        )
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"获取菜单路由失败：{str(e)}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="获取菜单路由失败"
        )


@router.get("/tree", response_model=BaseResponse[List[RouteResponse]])
async def get_route_tree(
    is_active: Optional[bool] = Query(True, description="是否启用"),
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(require_route_view)
):
    """获取路由树形结构"""
    try:
        result = await route_service.get_route_tree(db, is_active=is_active)
        
        return BaseResponse(
            data=result,
            message="获取路由树成功",
            success=True
        )
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"获取路由树失败：{str(e)}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="获取路由树失败"
        )


@router.post("", response_model=BaseResponse[RouteResponse])
async def create_route(
    route_data: RouteCreate,
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(require_route_manage)
):
    """
    创建路由
    
    - **path**: 路由路径（唯一）
    - **name**: 路由名称
    - **display_name**: 显示名称
    - **description**: 路由描述（可选）
    - **icon**: 图标名称（可选）
    - **component**: 组件路径（可选）
    - **parent_id**: 父路由ID（可选）
    - **sort_order**: 排序顺序
    - **is_menu**: 是否显示在菜单中
    - **meta**: 路由元数据（可选）
    """
    try:
        result = await route_service.create_route(db, route_data, current_user)
        
        return BaseResponse(
            data=result,
            message="路由创建成功",
            success=True
        )
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"创建路由失败：{str(e)}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="创建路由失败"
        )


# 具体路径的路由必须在参数路由之前定义，避免路径冲突

@router.get("/statistics", response_model=BaseResponse[dict])
async def get_route_statistics(
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(require_route_view)
):
    """获取路由访问统计"""
    try:
        result = await route_service.get_route_statistics(db)
        return BaseResponse(
            data=result,
            message="获取路由统计成功"
        )
    except HTTPException as e:
        raise e
    except Exception as e:
        logger.error(f"获取路由统计异常：{str(e)}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="获取统计失败"
        )



@router.put("/batch-sort", response_model=BaseResponse[List[RouteResponse]])
async def batch_update_route_sort(
    sort_data: List[dict],
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(require_route_manage)
):
    """批量更新路由排序"""
    try:
        result = await route_service.batch_update_sort(db, sort_data, current_user)
        return BaseResponse(
            data=result,
            message="路由排序更新成功"
        )
    except HTTPException as e:
        raise e
    except Exception as e:
        logger.error(f"批量更新路由排序异常：{str(e)}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="排序更新失败"
        )


@router.get("/{route_id}", response_model=BaseResponse[RouteResponse])
async def get_route(
    route_id: int,
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(require_route_view)
):
    """获取路由详情"""
    try:
        result = await route_service.get_route(db, route_id)
        
        return BaseResponse(
            data=result,
            message="获取路由详情成功",
            success=True
        )
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"获取路由详情失败：{str(e)}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="获取路由详情失败"
        )


@router.put("/{route_id}", response_model=BaseResponse[RouteResponse])
async def update_route(
    route_id: int,
    route_data: RouteUpdate,
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(require_route_manage)
):
    """更新路由"""
    try:
        result = await route_service.update_route(db, route_id, route_data, current_user)
        
        return BaseResponse(
            data=result,
            message="路由更新成功",
            success=True
        )
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"更新路由失败：{str(e)}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="更新路由失败"
        )


@router.delete("/{route_id}", response_model=BaseResponse[dict])
async def delete_route(
    route_id: int,
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(require_route_manage)
):
    """删除路由"""
    try:
        await route_service.delete_route(db, route_id, current_user)
        
        return BaseResponse(
            data={},
            message="路由删除成功",
            success=True
        )
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"删除路由失败：{str(e)}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="删除路由失败"
        )


@router.get("/{route_id}/permissions", response_model=BaseResponse[List[RoutePermissionResponse]])
async def get_route_permissions(
    route_id: int,
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(require_route_view)
):
    """获取路由权限关联"""
    try:
        result = await route_service.get_route_permissions(db, route_id)
        
        return BaseResponse(
            data=result,
            message="获取路由权限成功",
            success=True
        )
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"获取路由权限失败：{str(e)}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="获取路由权限失败"
        )


@router.post("/{route_id}/permissions", response_model=BaseResponse[dict])
async def assign_route_permissions(
    route_id: int,
    permission_data: RoutePermissionAssign,
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(require_route_manage)
):
    """分配权限给路由"""
    try:
        await route_service.assign_route_permissions(
            db, route_id, permission_data.permission_ids, current_user
        )
        
        return BaseResponse(
            data={},
            message="路由权限分配成功",
            success=True
        )
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"路由权限分配失败：{str(e)}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="路由权限分配失败"
        )


@router.delete("/{route_id}/permissions/{permission_id}", response_model=BaseResponse[dict])
async def remove_route_permission(
    route_id: int,
    permission_id: int,
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(require_route_manage)
):
    """移除路由权限关联"""
    try:
        await route_service.remove_route_permission(db, route_id, permission_id, current_user)
        
        return BaseResponse(
            data={},
            message="路由权限移除成功",
            success=True
        )
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"移除路由权限失败：{str(e)}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="移除路由权限失败"
        )



